From d529c3d93bb3e11d25c0d20d1aea5c97cfb1dcf6 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Mon, 4 Dec 2006 13:37:53 +0000 Subject: [PATCH] Added rudimentary "xend reload" functionality. This allows you to reconfigure the services offered by Xend, without restarting the daemon itself. Signed-off-by: Ewan Mellor --- tools/examples/init.d/xend | 5 +- tools/misc/xend | 4 +- tools/python/xen/xend/server/SrvDaemon.py | 8 ++ tools/python/xen/xend/server/SrvServer.py | 123 +++++++++++++--------- 4 files changed, 88 insertions(+), 52 deletions(-) diff --git a/tools/examples/init.d/xend b/tools/examples/init.d/xend index 8ad407637c..c12b1a0386 100755 --- a/tools/examples/init.d/xend +++ b/tools/examples/init.d/xend @@ -36,7 +36,10 @@ case "$1" in status) xend status ;; - restart|reload|force-reload) + reload) + xend reload + ;; + restart|force-reload) xend restart await_daemons_up ;; diff --git a/tools/misc/xend b/tools/misc/xend index b0ee27f556..c35fbf00e0 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -109,7 +109,7 @@ def main(): daemon = SrvDaemon.instance() if not sys.argv[1:]: - print 'usage: %s {start|stop|restart}' % sys.argv[0] + print 'usage: %s {start|stop|reload|restart}' % sys.argv[0] elif sys.argv[1] == 'start': if os.uname()[0] != "SunOS": start_xenstored() @@ -123,6 +123,8 @@ def main(): return daemon.start(trace=1) elif sys.argv[1] == 'stop': return daemon.stop() + elif sys.argv[1] == 'reload': + return daemon.reloadConfig() elif sys.argv[1] == 'restart': start_xenstored() start_consoled() diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 35c64869d4..155062a704 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -60,6 +60,14 @@ class Daemon: return running + def reloadConfig(self): + """ + """ + pid = read_pid(XEND_PID_FILE) + if find_process(pid, XEND_PROCESS_NAME): + os.kill(pid, signal.SIGHUP) + + def status(self): """Returns the status of the xend daemon. The return value is defined by the LSB: diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index f995a13bf9..1b0ed9c0db 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -65,6 +65,7 @@ class XendServers: def __init__(self): self.servers = [] self.cleaningUp = False + self.reloadingConfig = False def add(self, server): self.servers.append(server) @@ -78,6 +79,11 @@ class XendServers: except: pass + def reloadConfig(self, signum = 0, frame = None): + log.debug("SrvServer.reloadConfig()") + self.reloadingConfig = True + self.cleanup(signum, frame) + def start(self, status): # Running the network script will spawn another process, which takes # the status fd with it unless we set FD_CLOEXEC. Failing to do this @@ -86,61 +92,71 @@ class XendServers: fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC) Vifctl.network('start') - threads = [] - for server in self.servers: - thread = Thread(target=server.run, name=server.__class__.__name__) - if isinstance(server, HttpServer): - thread.setDaemon(True) - thread.start() - threads.append(thread) - - - # check for when all threads have initialized themselves and then - # close the status pipe - - threads_left = True - while threads_left: - threads_left = False - - for server in self.servers: - if not server.ready: - threads_left = True - break - - if threads_left: - time.sleep(.5) - - if status: - status.write('0') - status.close() # Prepare to catch SIGTERM (received when 'xend stop' is executed) # and call each server's cleanup if possible signal.signal(signal.SIGTERM, self.cleanup) + signal.signal(signal.SIGHUP, self.reloadConfig) - # Interruptible Thread.join - Python Bug #1167930 - # Replaces: for t in threads: t.join() - # Reason: The above will cause python signal handlers to be - # blocked so we're not able to catch SIGTERM in any - # way for cleanup - runningThreads = threads - while len(runningThreads) > 0: - try: - for t in threads: - t.join(1.0) - runningThreads = [t for t in threads - if t.isAlive() and not t.isDaemon()] - if self.cleaningUp and len(runningThreads) > 0: - log.debug("Waiting for %s." % - [x.getName() for x in runningThreads]) - except: - pass - - -def create(): - root = SrvDir() - root.putChild('xend', SrvRoot()) - servers = XendServers() + while True: + threads = [] + for server in self.servers: + thread = Thread(target=server.run, name=server.__class__.__name__) + if isinstance(server, HttpServer): + thread.setDaemon(True) + thread.start() + threads.append(thread) + + + # check for when all threads have initialized themselves and then + # close the status pipe + + threads_left = True + while threads_left: + threads_left = False + + for server in self.servers: + if not server.ready: + threads_left = True + break + + if threads_left: + time.sleep(.5) + + if status: + status.write('0') + status.close() + status = None + + # Interruptible Thread.join - Python Bug #1167930 + # Replaces: for t in threads: t.join() + # Reason: The above will cause python signal handlers to be + # blocked so we're not able to catch SIGTERM in any + # way for cleanup + runningThreads = threads + while len(runningThreads) > 0: + try: + for t in threads: + t.join(1.0) + runningThreads = [t for t in threads + if t.isAlive() and not t.isDaemon()] + if self.cleaningUp and len(runningThreads) > 0: + log.debug("Waiting for %s." % + [x.getName() for x in runningThreads]) + except: + pass + + if self.reloadingConfig: + log.info("Restarting all servers...") + self.cleaningUp = False + self.reloadingConfig = False + xroot.set_config() + self.servers = [] + _loadConfig(self) + else: + break + +def _loadConfig(servers): if xroot.get_xend_http_server(): servers.add(HttpServer(root, xroot.get_xend_address(), @@ -188,4 +204,11 @@ def create(): if xroot.get_xend_unix_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM)) + + +def create(): + root = SrvDir() + root.putChild('xend', SrvRoot()) + servers = XendServers() + _loadConfig(servers) return servers -- 2.30.2